﻿using System;
using System.Globalization;
using System.IO;
using Amazon.S3;
using Amazon.S3.Model;

namespace ICommonLibrary.Resource {

    public class AmazonS3Resource : IResource {
        
        public string Description { get; private set; }

        public AmazonS3 AmazonS3 { get; private set; }
        public string BucketName { get; private set; }
        public string Key { get; private set; }

        public AmazonS3Resource(AmazonS3 amazonS3, string bucketName, string key) {
            Asserts.NotNull(amazonS3, "AmazonS3 instance is null");
            Asserts.NotBlank(bucketName, "Bucket name is blank");
            Asserts.NotBlank(key, "Resource key is blank");

            AmazonS3 = amazonS3;
            BucketName = bucketName;
            Key = key;
            Description = string.Format("AmazonS3Resource[{0}/{1}]", BucketName, Key);
        }

        public Stream GetStream() {
            var request = new GetObjectRequest().WithBucketName(BucketName).WithKey(NormalizeKey(Key));

            using (GetObjectResponse response = AmazonS3.GetObject(request)) {
                return new MemoryStream(IOUtil.ReadAndClose(response.ResponseStream));
            }
        }

        public TextReader GetReader() {
            Stream stream = GetStream();
            return stream == null ? null : new StreamReader(stream);
        }

        public string GetPreSignedUrl() {
            var request = new GetPreSignedUrlRequest().WithBucketName(BucketName).WithKey(NormalizeKey(Key)).WithExpires(new DateTime(2038, 1, 1));
            return AmazonS3.GetPreSignedURL(request);
        }

        public static string NormalizeKey(string key) {
            key =  key.Replace('\\', '/');
            return key;
        }

        public static DateTime? GetDateModified(S3Response response) {
            var s = response.Headers.Get("Last-Modified");
            return DateTime.SpecifyKind(DateTime.ParseExact(s, "ddd, dd MMM yyyy HH:mm:ss \\G\\M\\T", CultureInfo.InvariantCulture), DateTimeKind.Utc);
        }

    }
}